package com.gaojinqi.base.common.service.imp;

import com.gaojinqi.base.core.jpa.BaseTreeRepository;
import com.gaojinqi.base.common.exception.BizRuntimeException;
import com.gaojinqi.base.common.model.BaseTreeEntity;
import com.gaojinqi.base.common.service.BaseTreeService;
import com.gaojinqi.base.common.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.Objects;
import java.util.Optional;

import static com.gaojinqi.base.common.constant.RespConst.RespEnum.PARENT_ID_REQUIRED;
import static com.gaojinqi.base.common.constant.RespConst.RespEnum.PARENT_INEXISTENCE;

/**
 * 通用树结构Service接口实现类
 *
 * @author gaojinqi
 * @version 1.0
 * @since 2020年05月08日
 */
public class BaseTreeServiceImpl<T extends BaseTreeEntity<ID>, ID extends Serializable>
        extends BaseServiceImpl<T, ID> implements BaseTreeService<T, ID> {

    @Autowired
    protected BaseTreeRepository<T, ID> treeRepository;

    public BaseTreeServiceImpl() {

    }

    @Override
    public void save(T entity) {
        if (entity.getParentId() == null) {
            throw new BizRuntimeException(PARENT_ID_REQUIRED);
        }
        setParentIds(entity);
        super.save(entity);
    }

    @Override
    public void update(T entity) {
        if (entity.getParentId() != null) {
            setParentIds(entity);
        }
        super.update(entity);
    }

    /**
     * 拼接查询条件
     * 1 ==> ,1,
     */
    private String setSearchParentIds(ID parentId) {
        if (parentId == null) {
            return null;
        }
        return SPLITTER + StringUtil.asString(parentId) + SPLITTER;
    }

    /**
     * 设置父ID路径
     */
    private void setParentIds(T entity) {
        String parentIds = null;
        if (Objects.equals(ROOT_PARENT_ID, StringUtil.asString(entity.getParentId()))) {
            // 处理根节点情况
            parentIds = SPLITTER + ROOT_PARENT_ID + SPLITTER;
        } else {
            // 处理非根节点情况
            Optional<T> parentOptional = treeRepository.findById(entity.getParentId());
            T parentEntity = parentOptional.orElseThrow(() -> new BizRuntimeException(PARENT_INEXISTENCE));
            parentIds = parentEntity.getParentIds();
            String parentIdStr = StringUtil.asString(parentEntity.getId());
            if (StringUtils.isEmpty(parentIds)) {
                parentIds = SPLITTER + parentIdStr + SPLITTER;
            } else {
                parentIds = parentIds + parentIdStr + SPLITTER;
            }
        }
        entity.setParentIds(parentIds);
    }

}
